import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Clase Mundo para el proyecto Rescue_Operation.
 * Es la que define al mundo y de donde se manejan
 * las principales acciones de los objetos mas importantes.
 * 
 * @author Programacion Orientada a Objetos( Jose de Jesus Cervantes Hernandez)
 */

public class Mundo extends World
{
    /**
     * Variable  del jugador principal que se maneja en todo el juego.
     */
    public Jugador heroe;  
    
    /**
     * Variable del primer enemigo (lagarto) que se manejara en el juego.
     */
    public Enemigos kong;          
    
    /**
     * Variable del segundo enemigo (barril) que se encuentra en el juego.
     */
    public barril bl;     
    
    /**
     * Variable del tercer enemigo (bomba)que se maneja en el juego.
     */
    public bombi bomba;                    
    
    /**
     * Variable del cuarto enemigo (rinoceronte) que se maneja en el juego.
     */
    public rambi ramb;                     //
   
    /**
     * Variable del el objeto banana que sirve para el cambio de niveles.
     */
    public banana ban; 
    
    /**
     * Variable del objeto vida que indica donde se dibujara el contador.
     */
    public vida vd;   
    
    /**
     * Variable que que sirve para mostrar las vidas del jugador
     */
    public count vidas;             
    
    /**
     * Variable para conservar las vidas entre nivel y nivel.
     */
    private int v;              
    
    /**
     * Variable que conserva el nivel en el cual se encuentra el jugador.
     */
    private int nivel=0;               
    
    /**
     * Variable que indica cuantos barriles se dibujaran en los diferentes niveles.
     */
    public int cont = 3;   
    
    /**
     * Varialbe que se usa para el manejo del timer que se muestra en pnatalla.
     */ 
    private Time timer;           
    
    /**
     * Variable que indica cuantos barriles se dibujaran en los diferentes niveles.
     */
    private int tp = 0;                    
    
    /**
     * Constructor para la clase Mundo.
     * El constructor iniciliza el mundo con la simulacion,
     * y manda llamar al metodo de menu, para dibujar el menu.
     */
    public Mundo()
    {    
        super(650, 485, 1);             //Crea un mundo de tamaño 650x485
        menu();                         //Funcion para que el menu este actuando y funcionen los botones
    }

    /**
     * Metodo Menu.
     * 
     * Este metodo permite controlar las opciones y las visualizaciones 
     * del menu principal del juego.
     */
    public void menu()
    {
        removeObjects(getObjects(null));
        setBackground("DonkeyKong.png");
        addObject(new ButtonStart(this), 547, 200);
        addObject(new ButtonHelp(this), 548, 280);
        addObject(new ButtonCredits(this), 547, 360);
    }

    /**
     * Este metodo se encarga de cambiar la imagen del 
     * fondo del mundo para mostrar la pantalla de ayuda.
     */
    public void help()
    {
        removeObjects(getObjects(null));
        setBackground("ayuda.png");
        addObject(new menu(this), 550, 450);
    }

    /**
     * Este metodo se encarga de cambiar la imagen del
     * fondo del mundo para mostrar la pantalla de los creditos.
     */
    public void credits()
    {
        removeObjects(getObjects(null));
        setBackground("creditos.png");
        addObject(new menu(this), 550, 450);
    }
    /**
     * Este Metodo se encarga de cargar el juego y verifica en que nivel se juega.
     */
    public void start()
    {
       presentacion1();
    }
    
    /**
     * Este Metodo se encarga de cargar el juego y verifica la presentacion.
     */
    public void run()
    {

        if(nivel <= 1)
        {
            niveles(1);
        }
        else if(nivel == 2)
        {
            niveles(2);
        }
        else if(nivel == 3)
        {
            niveles(3);
        }
    }
    
    /**
     * Metodo que verifica el nivel a jugar.
     */
    public void niveles(int p)
    {
        nivel = p;
        if(nivel == 1)
        {
           Nivel1();
        }
        else if(nivel == 2)
        {
            Nivel2();
        }
        else if(nivel == 3)
        {
            Nivel3();
        }
    }
    
    /**
     * Este es el metodo Act, que trae el mundo por default, solo se modifica para manejar el mundo y sus distintos niveles.
     */
    public void act()
    {
        if(nivel == 1)
        {
            if(cont < 6 )
            {
                dibujaBarril();
                cont++;
            }
        }
        else if(tp == 2)
        {
            if(cont < 9)
            {
                dibujaBarril();
                cont++;
            }
        }
        else if(tp == 3)
        {
            if(cont < 12)
            {
                dibujaBarril();
                cont++;
            }
        }
    }
    
    /**
     * Metodo para elegir a las presentaciones y definir cual corresponde a cada nivel.
     */
    public void presentaciones()
    {
        nivel++;
        
        if(nivel == 2)
        {
            presentacion2(2);
        }
        else if(nivel == 3)
        {
            presentacion3(3);
        }
    }
    
     /**
     * Metodo que indica la presentacion del nivel 1. 
     */
    public void presentacion1()
    {
            removeObjects(getObjects(null));
            setBackground("Niv1.png");
            addObject(new run(this), 543, 399);       
    }

     /**
     * Metodo que pone en pantalla  los requerimientos de vida y tiempo para el Nivel 1.
     */
    public void Nivel1()
    {
        nivel=1;
        removeObjects(getObjects(null));
        setBackground("Nivel1.png");
        timer = new Time();
        heroe = new Jugador();
        v = heroe.regresaVidas();
        vidas = new count(String.valueOf(v));
        addObject(timer, 500, 18);
        addObject(vidas, 85, 21);
        escenario1();
    }
     
    /**
     * Metodo donde manda llamar a cada objeto en la posicion adecuada del Nivel 1.
     */
    public void escenario1()
    { 
        addObject(new rock (this), 295, 252); 
        addObject(new rock (this), 479,252); 
        addObject(new rock (this), 162, 67); 
        addObject(new rock (this), 383, 67); 
        addObject(new rock (this), 320, 451);
        addObject(new rock (this), 500, 451);
        
        addObject(new plataformaOne (this), 58, 370);
        addObject(new plataformaOne (this), 105, 370);
        addObject(new plataformaOne (this), 468, 448);
        addObject(new plataformaOne (this), 347, 451);
        addObject(new plataformaOne (this), 405, 451);
        addObject(new plataformaOne (this), 231, 331);
        addObject(new plataformaOne (this), 99, 270);
        addObject(new plataformaOne (this), 214, 201);
        addObject(new plataformaOne (this), 56, 130);
        addObject(new plataformaOne (this), 81, 130);
        addObject(new plataformaOne (this), 209, 72);
        addObject(new plataformaOne (this), 276, 72);
        addObject(new plataformaOne (this), 347, 72);
        addObject(new plataformaOne (this), 646, 45);
        addObject(new plataformaOne (this), 586, 102);
        addObject(new plataformaOne (this), 445, 147);
        addObject(new plataformaOne (this), 581, 199);
        addObject(new plataformaOne (this), 342, 257);
        addObject(new plataformaOne (this), 441, 257);
        addObject(new plataformaOne (this), 596, 312);
        addObject(new plataformaOne (this), 481, 384);
        
        vida vd = new vida();
        addObject(vd, 265, 62);
        vida vd1 = new vida();
        addObject(vd1, 458, 248);
        
        Jugador heroe1 = new Jugador ();
        addObject(heroe1, 50, 360);
        
        Enemigos kong = new Enemigos(40, 1);
        addObject(kong, 237, 62);
        Enemigos kong2 = new Enemigos(40, 0);
        addObject(kong2, 450, 247);
        Enemigos kong3 = new Enemigos(40, 0);
        addObject(kong3, 350, 451);
        
       banana ban = new banana();
       addObject(ban, 617, 32); 
    }
    
    /**
     * Metodo que indica la presentacion del nivel 2
     */
    public void presentacion2(int p)
    {
        nivel = p;
        removeObjects(getObjects(null));
        setBackground("Niv2.png");
        addObject(new run(this), 543, 399);     
    }
     /**
     * Metodo que pone en pantalla los requerimientos de vida y tiempo para el Nivel 2
     */
    public void Nivel2()
    {
        nivel = 2;
        tp = 2;
        removeObjects(getObjects(null));
        setBackground("Nivel2.png");
        timer = new Time();
        heroe = new Jugador();
        heroe.actualizaVidas(v);
        vidas = new count(String.valueOf(v));
        addObject(timer, 500, 18);
        addObject(vidas, 85, 21);
        escenario2();
    }
    
     /**
     * Metodo donde manda llamar a cada objeto del nivel 2.
     */
    public void escenario2()
    {
        addObject(new rock (this), 140, 111);
        addObject(new rock (this), 10, 111);
        addObject(new rock (this), 82, 266);
        addObject(new rock (this), 0, 264);
        addObject(new rock (this), 642, 470);
        addObject(new rock (this), 409, 470);
        addObject(new rock (this), 189, 165);
        addObject(new rock (this), 394, 165);
        addObject(new rock (this), 185, 59);
        addObject(new rock (this), 484, 59);
        addObject(new rock (this), 402, 302);
        addObject(new rock (this), 650, 302);
        
        addObject(new plataformTwo (this), 49, 457);
        addObject(new plataformTwo (this), 161, 414);
        addObject(new plataformTwo (this), 45, 363);
        addObject(new plataformTwo (this), 170, 311);
        addObject(new plataformTwo (this), 41, 270);
        addObject(new plataformTwo (this), 170, 221); 
        addObject(new plataformTwo (this), 51, 170);
        addObject(new plataformTwo (this), 225, 170);
        addObject(new plataformTwo (this), 315, 170);
        addObject(new plataformTwo (this), 359, 170);
        addObject(new plataformTwo (this), 47, 116);
        addObject(new plataformTwo (this), 98, 116);
        addObject(new plataformTwo (this), 220, 65);
        addObject(new plataformTwo (this), 296, 65);
        addObject(new plataformTwo (this), 376, 65);        
        addObject(new plataformTwo (this), 453, 65);
        addObject(new plataformTwo (this), 571, 109);   
        addObject(new plataformTwo (this), 610, 160);
        addObject(new plataformTwo (this), 514, 214);
        addObject(new plataformTwo (this), 613, 262);
        addObject(new plataformTwo (this), 509, 307);
        addObject(new plataformTwo (this), 601, 307);
        addObject(new plataformTwo (this), 436, 307);
        addObject(new plataformTwo (this), 612, 357);
        addObject(new plataformTwo (this), 439, 413);
        addObject(new plataformTwo (this), 515, 413);
        addObject(new plataformTwo (this), 449, 475);
        addObject(new plataformTwo (this), 548, 475);
        addObject(new plataformTwo (this), 603, 475);
        
        vida vd = new vida();
        addObject(vd, 394, 150);
        vida vd1 = new vida();
        addObject(vd1, 641, 295);
        
        Jugador heroe1 = new Jugador ();
        addObject(heroe1, 52, 451);
        
        Enemigos kong = new Enemigos(40, 1);
        addObject(kong, 94, 106);
        Enemigos kong2 = new Enemigos(40, 0);
        addObject(kong2, 47, 262);
        Enemigos kong3 = new Enemigos(40, 0);
        addObject(kong3, 544, 466);
        
        bombi bomba = new bombi();
        addObject(bomba, 359, 162);
        bombi bomba2 = new bombi();
        addObject(bomba2, 376, 54);
        bombi bomba3 = new bombi();
        addObject(bomba3, 484, 300);
        
        banana ban = new banana();
        addObject(ban, 462, 461); 
  
    }
    
    /**
     * Metodo que indica la presentacion del nivel 3
     */
    public void presentacion3(int p)
    {
        nivel = p;
        removeObjects(getObjects(null));
        setBackground("Niv3.png");
        addObject(new run(this), 543, 399);     
    }
    
     /**
     * Metodo que pone en pantalla los requerimientos de las vidas y el tiempo necesario para el Nivel 2
     */
    public void Nivel3()
    {
        nivel = 3;
        tp = 3;
        removeObjects(getObjects(null));
        setBackground("Nivel3.png");
        timer = new Time();
        heroe = new Jugador();
        heroe.actualizaVidas(v);
        vidas = new count(String.valueOf(v));
        addObject(timer, 500, 18);
        addObject(vidas, 85, 21);
        escenario3();
    }
    
     /**
     * Metodo donde manda llamar a cada objeto del nivel 3.
     */
     public void escenario3()
    {
       
        addObject(new plataform3 (this), 75, 63);
        addObject(new plataform3 (this), 227, 100);
        addObject(new plataform3 (this), 350, 100);
        addObject(new plataform3 (this), 464, 100);
        addObject(new plataform3 (this), 584, 157);
        addObject(new plataform3 (this), 439, 201); 
        addObject(new plataform3 (this), 313, 199);
        addObject(new plataform3(this), 179, 241);
        addObject(new plataform3 (this), 289, 333);
        addObject(new plataform3(this), 596, 333);
        addObject(new plataform3 (this), 61, 240);
        addObject(new plataform3(this), 545, 255);
        addObject(new plataform3 (this), 35, 359);
        addObject(new plataform3(this), 596, 333);
        addObject(new plataform3 (this), 146, 359);
        addObject(new plataform3(this), 510, 332);
        addObject(new plataform3 (this), 402, 437);
        addObject(new plataform3(this), 554, 465);
         addObject(new plataform3 (this), 259, 463);
        addObject(new plataform3(this), 137, 463);
        addObject(new plataform3 (this), 39, 461);
        
        addObject(new rock (this), 166, 103);
        addObject(new rock (this), 524, 103);
        addObject(new rock (this), 499, 205);
        addObject(new rock (this), 250, 205);
        addObject(new rock (this), 238, 246);
        addObject(new rock (this), 10, 244);
        addObject(new rock (this), 639, 340);
        addObject(new rock (this), 446, 340);
        addObject(new rock (this), 207, 365);
        addObject(new rock (this), 12, 363);
        addObject(new rock (this), 491, 471);
        addObject(new rock (this), 615, 471);
        addObject(new rock (this), 318, 468);
        addObject(new rock (this), 10, 467);

        vida vd = new vida();
        addObject(vd, 579, 461);
        vida vd1 = new vida();
        addObject(vd1, 51, 354);
        
        Jugador heroe1 = new Jugador ();
        addObject(heroe1, 52, 63);
        
        Enemigos kong = new Enemigos(40, 1);
        addObject(kong, 528, 466);
        Enemigos kong2 = new Enemigos(40, 0);
        addObject(kong2, 182, 363);
        Enemigos kong3 = new Enemigos(40, 0);
        addObject(kong3, 340, 204);
        
        bombi bomba = new bombi();
        addObject(bomba, 29, 242);
        bombi bomba2 = new bombi();
        addObject(bomba2, 483, 335);
        
        rambi ramb = new rambi();
        addObject(ramb, 379, 100);
        rambi ramb1 = new rambi();
        addObject(ramb1, 133, 469);;
        
        banana ban = new banana();
        addObject(ban, 73, 460); 
    }
    
    /**
     * Metodo que manda llamar al objeto del jugador y este aumenta su vida. 
     */
    public void sumaVida()
    {
        heroe.aumentaVida();
        v = heroe.regresaVidas();
        vidas.actualizaCount(String.valueOf(v));
    }
    
    /**
     * Metodo que manda llamar al objeto del jugador y restar la vida.
     */
    public void restaVida(int t)
    {
        heroe.disminuyeVida(t);
        v = heroe.regresaVidas();
        vidas.actualizaCount(String.valueOf(v));
        dead();
    }

     /**
     * Metodo para modificar el tiempo actual del juego
     */
    public void aumentaTiempo()
    {
        timer.sumaTime();
    }
    
     /**
     * Metodo para abreviar el remover un Objeto Actor, sirve para que otros objetos eliminen desde aqui
     */
    public void elimina(Actor a)
    {
        removeObject(a);
    }
    
    /**
     * Metodo que controla la caida de los barriles.
     */
    public void dibujaBarril()
    {
        barril bl1 = new barril();
        addObject(bl1, Greenfoot.getRandomNumber(640),10);
    }
    
    /**
     * Metodo que disminuye un barril al momento que desaparece del Mundo.
     */
    public void disminuye(int t)
    {
       cont = cont - (t);
    }
    
    /**
     * Metodo que indica la perdida de todas las vidas del Jugador.
     */
    public void dead()
    {
        if(v <= 0)
        {
            removeObjects(getObjects(null));
            setBackground("dead.jpg");
            nivel = 1;
            addObject(new menu(this), 550, 450);
        }
    }
}
